/**
 * 
 */
package xj.toolkit.bean.bytebean.codec;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;

import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Lists;

import xj.toolkit.bean.bytebean.core.ByteFieldDesc;
import xj.toolkit.bean.bytebean.core.Field2Desc;
import xj.toolkit.util.SimpleCache;


/**
 * @author isdom
 *
 */
public class BeanCodecUtil {
    
    @SuppressWarnings("unused")
    private static final Logger logger = LoggerFactory.getLogger(BeanCodecUtil.class);
    
    private Field2Desc                      field2Desc;
    private SimpleCache<Class<?>, List<ByteFieldDesc>>   descesCache = 
        new SimpleCache<Class<?>, List<ByteFieldDesc>>();
    private boolean cached = true;
    
    /**
     * 添加是否使用缓存选项。
     * 
     * @param field2Desc
     * @param cached
     */
    public BeanCodecUtil(Field2Desc field2Desc, boolean cached) {
        this.field2Desc = field2Desc;
        this.cached =  cached;
    }
    
    public List<ByteFieldDesc> getFieldDesces(final Class<?> clazz) {
    	
    	if (!cached) {
    		return getByteFieldDesc(clazz);
    	}
    	
        return  descesCache.get(clazz, new Callable<List<ByteFieldDesc>>(){

            public List<ByteFieldDesc> call(){
            	return getByteFieldDesc(clazz);
            }});
    }
    
    private List<ByteFieldDesc> getByteFieldDesc(Class<?> clazz) {
        List<ByteFieldDesc> ret;
        
        Field[] fields = null;
        
        Class<?> itr = clazz;
        while ( !itr.equals(Object.class)) {
            fields = ArrayUtils.addAll(itr.getDeclaredFields(), fields);
            itr = itr.getSuperclass();
            if (itr == null) {
            	break;
            }
        }
        
        ret = new ArrayList<ByteFieldDesc>(fields.length);
        for ( Field field : fields ) {
            ByteFieldDesc desc = field2Desc.genDesc(field);
            if ( null != desc ) {
                ret.add(desc);
            }
        }
        
        if (ret == null || ret.size() == 0) {
        	return Lists.newArrayList();
        }
        
        Collections.sort(ret, ByteFieldDesc.comparator);
        return  ret;
    
    }
}
